home *** CD-ROM | disk | FTP | other *** search
/ PCMania 30 / PCMania CD30.iso / pcmania / graf30 / dtiff2.c < prev    next >
Text File  |  1988-11-28  |  9KB  |  274 lines

  1. /*****************************************************************************
  2.  DTIFF2.C - DTIFF2, Display Tag Image File Format.
  3.  Modified by Tom Cervenka for Late Night Software, (c) 1988
  4.  All Rights Reserved.
  5.  
  6.  This code was modified from source mentioned in BYTE Vol 13, Num 11,
  7.  "IBM Special Edition", "VGA VIDEO MODES", p. 187, by Richard Wilton
  8.  and downloaded via BIX LISTINGS Conference.
  9.  
  10.  *****************************************************************************/
  11. /******************************************************************************
  12. *                                                                             *
  13. * Name:      gvmode.c                                                         *
  14. *                                                                             *
  15. * Function:  program VGA CRTC in graphics modes                               *
  16. *                                                                             *
  17. * Syntax:    GVMODE <horizontal pixels> <vertical pixels> [adjust]            *
  18. *                                                                             *
  19. ******************************************************************************/
  20.  
  21. #include       <stdio.h>
  22. #include        <dos.h>
  23. #define outpw(portid,v)    outport(portid,v)
  24.  
  25. #define    DOTRATE0    25.175E6
  26. #define    DOTRATE1    28.322E6
  27. #define    CHARHEIGHT    16             /* (should be 8, 14, or 16) */
  28.  
  29. int far *ADDR_6845 = (int far *)0x00400063;
  30. union REGS    regs;                      /* used by int86() */
  31.  
  32. char *vgaxset( int HPixels, int VPixels, int HAdjust )
  33. {
  34.     float    DotRate;
  35.     float    LineRate;
  36.     float    FrameRate;
  37.     float    HSyncDuration = 3.813E-6;     /* duration of HSync signal */
  38.     int    CharWidth = 8;             /* size of displayed characters */
  39.     int    CharHeight = CHARHEIGHT;
  40.  
  41.     /* ROM BIOS data values */
  42.     unsigned int  far *CRT_COLS = (int far *)0x0040004A;
  43.     unsigned int  far *CRT_LEN  = (int far *)0x0040004C;
  44.  
  45.     int    Cols;            /* number of displayed character columns */
  46.     int    HSyncTime;              /* number of horiz sync clocks */
  47.     int    HOverscan = 8;            /* number of overscan clocks */
  48.     int    HTotal;               /* total clocks in one horiz scan */
  49. /*    int    HAdjust = 0;    */            /* horizontal adjustment */
  50. /*    int    HPixels;    */          /* number of horizontal pixels */
  51.     int    VOverscan = 16;            /* number of overscan scan lines */
  52.     int    VSyncTime = 2;     /* number of scan lines of vert sync signal */
  53.     int    VRetrTime = 30;     /* number of scan lines of vertical retrace */
  54. /*    int    VPixels; */       /* number of vertical pixels (scan lines) */
  55.  
  56.     int    CRTCval[0x19];                 /* values for CRTC regs */
  57.     int    i;
  58.  
  59. /* check args */
  60.  
  61.     if( HPixels % 16 )
  62.     {
  63.       return("Error: Horizontal pixel count must be a multiple of 16\n");
  64.     }
  65.  
  66. /* start with either 640x350 or 640x480 16-color graphics mode */
  67.  
  68.     regs.x.ax = ( (VPixels <= 350) ? 0x0010 : 0x0012 );
  69.     int86( 0x10, ®s, ®s );
  70.  
  71. /* call BIOS to select displayed character matrix */
  72.  
  73.     regs.x.ax = 0x1100;
  74.     switch( CharHeight )
  75.     {
  76.       case 8:
  77.         regs.x.ax += 0x23;            /* use 8x8 character definitions */
  78.         break;
  79.  
  80.       case 14:
  81.         regs.x.ax += 0x22;           /* use 8x14 character definitions */
  82.         break;
  83.  
  84.       case 16:
  85.         regs.x.ax += 0x24;           /* use 8x14 character definitions */
  86.         break;
  87.     }
  88.  
  89.     regs.x.bx = 0;
  90.     regs.x.dx = VPixels / CharHeight;     /* number of character rows */
  91.     int86( 0x10, ®s, ®s );
  92.  
  93. /* select dot clock */
  94.  
  95.     i = inp( 0x3CC );            /* read Miscellaneous Output reg */
  96.     i &= 0xF3;                  /* bits 2-3 = 00b (25.172 MHz) */
  97.  
  98.     if( (unsigned)((HPixels/CharWidth)*VPixels) > (unsigned)((640/8)*480) )
  99.       i |= 4;                  /* bits 2-3 = 01b (28.322 MHz) */
  100.  
  101.     VRwait();
  102.     SetSeqReg( 0, 1 );              /* synchronous Sequencer reset */
  103.     outp( 0x3C2, i );               /* update Misc Output reg */
  104.     SetSeqReg( 0, 3 );                /* clear Sequencer reset */
  105.  
  106. /* compute CRTC horizontal and vertical timing parameters */
  107.  
  108.     DotRate = ( ((inp(0x3CC) & 0x0C) == 0) ? DOTRATE0 : DOTRATE1);
  109.  
  110.     HSyncTime =          /* duration of Horiz Sync signal (rounded) */
  111.       ( (DotRate * HSyncDuration) / (float)CharWidth ) + 0.5;
  112.  
  113.     Cols = HPixels / CharWidth;
  114.  
  115.     HTotal = Cols + HSyncTime + HOverscan;
  116.  
  117.     for( i=0; i<=0x18; i++ )     /* get current CRTC register values */
  118.       CRTCval[i] = GetCRTCReg( i );
  119.  
  120.     CRTCval[0] = HTotal - 5;                /* Reg 0: Horiz Total */
  121.     CRTCval[1] = Cols - 1;             /* Reg 1: Horiz Disp Enable End */
  122.     CRTCval[2] = Cols;             /* Reg 2: Start Horiz Blank */
  123.     CRTCval[3] = ((HTotal-2) & 0x1F) | 0x80;   /* Reg 3: End Horiz Blank */
  124.     CRTCval[4] = Cols + HAdjust + 4;           /* Reg 4: Start Hsync */
  125.     CRTCval[5] =                     /* Reg 5: End Hsync */
  126.       ((CRTCval[4] + HSyncTime) & 0x1F) |             /* bits 0-4 */
  127.       (((HTotal-2) & 0x20) << 2);                    /* bit 7 */
  128.     CRTCval[0x13] = Cols / 2;             /* Reg 0x13: Offset */
  129.  
  130.     CRTCval[6] =                    /* Reg 6: Vertical Total */
  131.       VPixels + VOverscan + VSyncTime + VRetrTime - 2;
  132.     CRTCval[0x10] =                 /* Reg 0x10: Vert Retrace Start */
  133.       VPixels + (VOverscan+VRetrTime)/2;
  134.     CRTCval[0x11] =                   /* Reg 0x11: Vert Retrace End */
  135.       (CRTCval[0x11] & 0xF0) |                 /* bits 4-7 */
  136.       ((CRTCval[0x10] + VSyncTime) & 0x0F);             /* bits 0-3 */
  137.     CRTCval[0x12] = VPixels - 1;    /* Reg 0x12: Vert Display Enable End */
  138.     CRTCval[0x15] =                /* Reg 0x15: Start Vert Blank */
  139.       VPixels + VOverscan/2;
  140.     CRTCval[0x16] =                 /* Reg 0x16: End Vert Blank */
  141.       CRTCval[6] - VOverscan/2 + 2;
  142.     CRTCval[7] =                      /* Reg 7: Overflow */
  143.       ((CRTCval[0x10] & 0x200) >> 2) |                /* bit 7 */
  144.       ((CRTCval[0x12] & 0x200) >> 3) |                /* bit 6 */
  145.       ((CRTCval[6] & 0x200) >> 4) |                    /* bit 5 */
  146.       (CRTCval[7] & 0x10) |                        /* bit 4 */
  147.       ((CRTCval[0x15] & 0x100) >> 5) |                /* bit 3 */
  148.       ((CRTCval[0x10] & 0x100) >> 6) |                /* bit 2 */
  149.       ((CRTCval[0x12] & 0x100) >> 7) |                /* bit 1 */
  150.       ((CRTCval[6] & 0x100) >> 8);                    /* bit 0 */
  151.     CRTCval[9] =                     /* Reg 9: Max Scan Line */
  152.       (CRTCval[9] & 0xDF) | ((CRTCval[0x15] & 0x200) >> 4);        /* bit 5 */
  153.  
  154. /* program the CRTC with new timing parameters */
  155.  
  156.     CRTCval[0x11] &= 0x7F;               /* disable CRTC write-protect */
  157.     SetCRTCReg( 0x11, CRTCval[0x11] );
  158.  
  159.     for( i=0; i<=0x18; i++ )
  160.       SetCRTCReg( i, CRTCval[i] );             /* update CRTC regs */
  161.  
  162.     CRTCval[0x11] |= 0x80;            /* enable CRTC write-protect */
  163.     SetCRTCReg( 0x11, CRTCval[0x11] );
  164.  
  165.     SetATCReg( 0x11, 1 );     /* set a blue border (for screen alignment) */
  166.  
  167. /* update BIOS data area */
  168.  
  169.     *CRT_COLS = Cols;
  170.     *CRT_LEN = ((VPixels * Cols * 2) + 0xFFF) & 0xF000;
  171.  
  172. /* display register values and timings */
  173. /*
  174.     printf( "\nDisplayed resolution is %d by %d pixels",
  175.       HPixels, VPixels );
  176.     printf( "\nDisplayed character matrix is %d by %d pixels",
  177.       CharWidth, CharHeight );
  178.  
  179.     printf( "\n\nCRTC registers:\n" );    /* show CRTC register values */
  180.     for( i=0; i<=0x18; i++ )
  181.       printf( " %2X", i );
  182.  
  183.     printf( "\n" );
  184.     for( i=0; i<=0x18; i++ )
  185.       printf( " %2X", GetCRTCReg( i ) );
  186.  
  187.     LineRate =                    /* scan lines per second */
  188.       DotRate / (float)((CRTCval[0]+5)*CharWidth);
  189.     i = ((GetCRTCReg(7) & 0x20) << 4)     /* vertical total (scan lines) */
  190.         + ((GetCRTCReg(7) & 0x1) << 8)
  191.         + GetCRTCReg(6) + 2;
  192.     FrameRate = LineRate / (float)i;        /* frames per second */
  193.  
  194.     printf( "\n\nDot rate = %6.3f MHz, %d dots/char",
  195.         DotRate/1E6, CharWidth );
  196.     printf( "\nLine rate  = %5.2f KHz", LineRate/1E3 );
  197.     printf( "\nFrame rate = %4.1f Hz\n", FrameRate );
  198. */
  199.     return(NULL);
  200. }
  201.  
  202. SetCRTCReg( r, v )                   /* update a CRTC register */
  203. int    r;        /* register number */
  204. int    v;        /* 8-bit value */
  205. {
  206.     outpw( *ADDR_6845, (v<<8) | r );
  207. }
  208.  
  209. GetCRTCReg( r )                         /* read a CRTC register */
  210. int    r;        /* register number */
  211. {
  212.     outp( *ADDR_6845, r );
  213.     return inp( *ADDR_6845+1 );
  214. }
  215.  
  216. SetSeqReg( r, v )                  /* update a Sequencer register */
  217. int    r;
  218. int    v;
  219. {
  220.     outpw( 0x3C4, (v<<8) | r );
  221. }
  222.  
  223. SetATCReg( r, v )             /* set an Attribute Controller register */
  224. int    r;
  225. int    v;
  226. {
  227.     regs.x.ax = 0x1000;
  228.     regs.h.bh = v;
  229.     regs.h.bl = r;
  230.     int86( 0x10, ®s, ®s );       /* use video BIOS to set register */
  231. }
  232.  
  233. VRwait()                    /* wait for vertical retrace */
  234. {
  235.     register int CRTStatusPort = *ADDR_6845 + 6;
  236.  
  237.     while( (inp( CRTStatusPort ) & 8) != 0 );
  238.     while( (inp( CRTStatusPort ) & 8) == 0 );
  239. }
  240.  
  241. /* The following code was written by Tom Cervenka */
  242.  
  243. extern int MaxX;
  244.  
  245. void vgaxputpixel(int x, int y, int color)
  246. {
  247.  unsigned offset;
  248.  static unsigned char far *pixpos;
  249.  
  250.  offset=(x/8)+(y*((MaxX+1)/8));
  251.  pixpos=MK_FP(0xa000,offset);
  252.  *pixpos=(*pixpos)|(1<<(7-(x%8)));
  253. }
  254.  
  255. void hercputpixel(int x, int y, int color)
  256. {
  257.  unsigned offset;
  258.  static unsigned char far *pixpos;
  259.  
  260.  offset=(0x2000*(y%4))+(90*(y/4))+(x/8);
  261.  pixpos=MK_FP(0xB000,offset);
  262.  *pixpos=(*pixpos)&(~(1<<(7-(x%8))));
  263. }
  264.  
  265. void cgaputpixel(int x, int y, int color)
  266. {
  267.  unsigned offset;
  268.  static unsigned char far *pixpos;
  269.  
  270.  offset=(0x2000*(y%2))+(80*(y/2))+(x/8);
  271.  pixpos=MK_FP(0xB800,offset);
  272.  *pixpos=(*pixpos)&(~(1<<(7-(x%8))));
  273. }
  274.